package com.rytong.tools.crypto;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

import com.rytong.tools.utils.Utils;

public class DESCipher {
    Cipher cipher_;
    static byte[] key_;
    boolean isnopadding_;

    private Cipher getInstance(boolean nopadding) {
        Cipher cipher;
        try {
            if (null == cipher_) {
                if (nopadding)
                    cipher = Cipher.getInstance("DES/ECB/NOPadding");
                else
                    cipher = Cipher.getInstance("DES/ECB/PKCS7Padding");
                return cipher;
            }
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            Utils.printException(e);
        } catch (NoSuchPaddingException e) {
            // TODO Auto-generated catch block
            Utils.printException(e);
        }
        return cipher_;
    }

    private String Encrypt(String plantText, byte[] key) {
        String cipherText = null;

        try {
            cipher_ = getInstance(isnopadding_);
            byte[] inblock = plantText.getBytes("UTF-8");
            cipher_.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "DES"));
            byte[] outblock = callCipher(inblock);
            cipherText = Base64.encode(outblock);
        } catch (Exception e) {
            Utils.printException(e);
        }
        return cipherText;

    }

    private byte[] Decrypt(String cipherText) {
        String plantText = null;
        byte[] inblock = null;
        byte[] outblock = null;
        try {
            cipher_ = getInstance(isnopadding_);
            inblock = Base64.decodeToBytes(cipherText);
            cipher_.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key_, "DES"));
            outblock = callCipher(inblock);
        } catch (Exception ex) {
            Utils.printException(ex);
        }
        return outblock;
    }

    private byte[] callCipher(byte[] data) {
        byte[] result = null;
        try {
            int size = cipher_.getOutputSize(data.length);
            result = new byte[size];
            int olen = cipher_.update(data, 0, data.length, result, 0);
            olen += cipher_.doFinal(result, olen);
            if (olen < size) {
                byte[] tmp = new byte[olen];
                System.arraycopy(result, 0, tmp, 0, olen);
                result = tmp;
            }
        } catch (Exception e) {
            Utils.printException(e);
        }
        return result;
    }

    public static String doEncrypt(String plantText, byte[] keyArray) {
        String cipherText = null;
        key_ = keyArray;
        DESCipher desCipher = new DESCipher();
        desCipher.isnopadding_ = false;
        cipherText = desCipher.Encrypt(plantText, key_);
        return cipherText;

    }

    public static String doDecrypt(String cipherText, byte[] keyArr) throws UnsupportedEncodingException {
        String plantText = null;
        DESCipher desCipher = new DESCipher();
        key_ = keyArr;
        desCipher.isnopadding_ = false;
        plantText = new String(desCipher.Decrypt(cipherText), "UTF-8");
        return plantText;
    }

    public static byte[] doDecryptWithoutPadding(String cipherText, byte[] keyArray) {
        byte[] plantText = null;
        key_ = keyArray;
        DESCipher desCipher = new DESCipher();
        desCipher.isnopadding_ = true;
        plantText = desCipher.Decrypt(cipherText);
        return plantText;
    }

}
